#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   APP_ControlDTCSetting_0x85_test.py
@Time    :   2025/04/03 13:31:28
@Author  :   YangLiang 
@Version :   1.0
@Contact :   yangl@genvict.com
@License :   (C)Copyright 2022-2025
@Desc    :   UDS 0x85 DTC控制服务测试
'''

from pytest_assume.plugin import assume
import pytest
import logging
import time
from commDriver.TS_CAN import *
import allure
import sys
sys.dont_write_bytecode = True

# region 测试数据定义
ControlDTCSetting = [
    ("85 01", "C5 01"),             # 子功能01
    ("85 02", "C5 02"),             # 子功能02
    ("85 81", ""),                  # 抑制响应
    ("85 82", "")                   # 抑制响应
]

ControlDTCSetting_NRC7F = [
    ("85 01", "7F 85 7F"),          # 
    ("85 02", "7F 85 7F"),          #
    ("85 81", "7F 85 7F"),          #
    ("85 82", "7F 85 7F"),          #
    ("85 03", "7F 85 7F"),          # 子功能03 7F>12
    ("85 84", "7F 85 7F"),          # 子功能04 7F>12
    ("85 01 00", "7F 85 7F"),       # 子功能04 7F>13
    ("85 81 00", "7F 85 7F"),       # 子功能04 7F>13
]

ControlDTCSetting_NRC13 = [
    ("85 01 01", "7F 85 13"),       # 缺失控制类型
    ("85 01 01 00", "7F 85 13"),    # 多余参数
    ("85 81 01", "7F 85 13"),       # 抑制响应
    ("85 82 02", "7F 85 13"),       # 抑制响应
    ("85", "7F 85 13"),             # 
    ("85 82 01 00 00", "7F 85 13")  # 抑制响应
]

ControlDTCSetting_NRC12 = [
    ("85 00", "7F 85 12"),          # 无效子功能00
    ("85 03", "7F 85 12"),          # 无效子功能03
    ("85 80", "7F 85 12"),          # 
    ("85 83", "7F 85 12"),          # 
    ("85 FF", "7F 85 12"),
    ("85 83 FF", "7F 85 12"),       #
    ("85 00 01", "7F 85 12"),       #     
]

# 有NRC22要求,但是没有NRC22条件
ControlDTCSetting_NRC22 = [
    ("85 01", "7F 85 22"),          # 条件不满足
    ("85 02", "7F 85 22")           # 条件不满足
]
# endregion

# region 物理寻址测试
class Test_APP_ControlDTCSetting_Phy:
    """物理寻址模式测试（仅支持扩展会话）"""
    
    @allure.severity('normal')
    @allure.title('物理寻址-扩展会话-正响应测试')
    @allure.description('物理寻址扩展会话下正响应')
    @pytest.mark.parametrize('req,resp', ControlDTCSetting,
                           ids=[f"Request {req}" for req, _ in ControlDTCSetting])
    def test_ControlDTCSetting_Extended_Phy(self, action, Driver, req, resp):
        iStep = 1
        # 执行测试步骤
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)

    @allure.severity('normal')
    @allure.title('物理寻址-默认会话-NRC7F测试')
    @allure.description('物理寻址默认会话下NRC7F')
    @pytest.mark.parametrize('req,resp', ControlDTCSetting_NRC7F,
                           ids=[f"Request {req}" for req, _ in ControlDTCSetting_NRC7F])
    def test_ControlDTCSetting_NRC7F_Default_Phy(self, action, Driver, req, resp):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, req, resp, 1, iStep, False)

    @allure.severity('normal')
    @allure.title('物理寻址-扩展会话-NRC13测试')
    @allure.description('物理寻址扩展会话下NRC13')
    @pytest.mark.parametrize('req,resp', ControlDTCSetting_NRC13,
                           ids=[f"Request {req}" for req, _ in ControlDTCSetting_NRC13])
    def test_ControlDTCSetting_NRC13_Extended_Phy(self, action, Driver, req, resp):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)

    @allure.severity('normal')
    @allure.title('物理寻址-扩展会话-NRC12测试')
    @allure.description('物理寻址扩展会话下NRC12')
    @pytest.mark.parametrize('req,resp', ControlDTCSetting_NRC12,
                           ids=[f"Request {req}" for req, _ in ControlDTCSetting_NRC12])
    def test_ControlDTCSetting_NRC12_Extended_Phy(self, action, Driver, req, resp):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)

    # 没有NRC22条件,但是有NRC22要求
    # @allure.severity('normal')
    # @allure.title('扩展会话-NRC22测试')
    # @pytest.mark.parametrize('req,resp', ControlDTCSetting_NRC22,
    #                        ids=[f"Req:{req}" for req, _ in ControlDTCSetting_NRC22])
    # def test_ControlDTCSetting_NRC22_Extended_Phy(self, action, Driver, req, resp):
    #     iStep = 1
    #     iStep, _, _ = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)

    @allure.severity('critical')
    @allure.title('物理寻址-扩展会话-NRC12/NRC13优先级验证')
    @allure.description('验证物理寻址扩展会话下NRC响应顺序：12 > 13')
    def test_ControlDTCSetting_NRC12_NRC13_Priority_Extended_Phy(self, action, Driver):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '85 05 01', '7F 85 12', 3, iStep, False)

    @allure.severity('critical')
    @allure.title('物理寻址-默认会话-NRC7F/NRC22优先级验证')
    @allure.description('验证物理寻址默认会话下NRC响应顺序：7F > 22')
    def test_ControlDTCSetting_NRC7F_NRC22_Priority_Default_Phy(self, action, Driver):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '10 01', '50 01', 0, iStep, False)
        iStep = Driver['CAN'].SetVehicleSpeed(Driver, iStep, 5)
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '85 01', '7F 85 7F', 0, iStep, False)
        iStep = Driver['CAN'].SetVehicleSpeed(Driver, iStep, 0)
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '85 01', '7F 85 7F', 0, iStep, False)

    @allure.severity('critical')
    @allure.title('物理寻址-扩展会话-关闭DTC控制功能验证')
    @allure.description('验证物理寻址扩展会话下关闭DTC控制功能验证')
    def test_ControlDTCSetting_OFF_Extended_Phy(self, action, Driver):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '10 03', '50 03', 0, iStep, False)
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '14 FF FF FF', '54', 0, iStep, False)
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '19 02 09', '59 02 09', 0, iStep, False)
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '85 02', 'C5 02', 0, iStep, False)
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
        # 设置电源电压为8v并等待3.5s,生成低压故障
        iStep = Driver['CAN'].SetVolt(Driver, 8.3, 2, iStep)
        for i in range(2): # 重复2次
            with allure.step(f'Step{iStep}:等待3s'): # type: ignore
                iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
                time.sleep(2)
                iStep += 1
        with allure.step(f'Step{iStep}:关闭DTC检测,应无法生成低压故障 # NA'): # type: ignore
            a,b,c=Driver['UDS'].search_DTC([0x19, 0x02, 0x09], [0x91, 0x17, 0x16, 0x09], 1)
            with assume: assert a == False, logging.error('检测到低压故障,未关闭DTC控制功能')
            iStep += 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '85 01', 'C5 01', 0, iStep, False)
        for i in range(2): # 重复2次
            with allure.step(f'Step{iStep}:等待3s'): # type: ignore
                iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
                time.sleep(2)
                iStep += 1
        with allure.step(f'Step{iStep}:打开DTC检测,应生成低压故障 # NA'): # type: ignore
            a,b,c=Driver['UDS'].search_DTC([0x19, 0x02, 0x09], [0x91, 0x17, 0x16, 0x09], 1)
            with assume: assert a == True, logging.error('未检测到低压故障,未打开DTC控制功能')
            iStep += 1
        iStep = Driver['CAN'].SetVolt(Driver, 12, 1, iStep)
# endregion

# region 功能寻址测试
class Test_APP_ControlDTCSetting_Func:
    """功能寻址模式测试（仅支持扩展会话）"""
    
    @allure.severity('normal')
    @allure.title('功能寻址-扩展会话-正响应测试')
    @allure.description('功能寻址扩展会话下正响应')
    @pytest.mark.parametrize('req,resp', ControlDTCSetting,
                           ids=[f"Request {req}" for req, _ in ControlDTCSetting])
    def test_ControlDTCSetting_Extended_Func(self, action, Driver, req, resp):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False, 'UDSFun')

    @allure.severity('normal')
    @allure.title('功能寻址-默认会话-NRC7F测试')
    @allure.description('功能寻址默认会话下NRC7F')
    @pytest.mark.parametrize('req,resp', ControlDTCSetting_NRC7F,
                           ids=[f"Req:{req}" for req, _ in ControlDTCSetting_NRC7F])
    def test_ControlDTCSetting_NRC7F_Default_Func(self, action, Driver, req, resp):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, req, '', 1, iStep, False, 'UDSFun')

    @allure.severity('normal')
    @allure.title('功能寻址-扩展会话-NRC13测试')
    @allure.description('功能寻址扩展会话下NRC13')
    @pytest.mark.parametrize('req,resp', ControlDTCSetting_NRC13,
                           ids=[f"Req:{req}" for req, _ in ControlDTCSetting_NRC13])
    def test_ControlDTCSetting_NRC13_Extended_Func(self, action, Driver, req, resp):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False, 'UDSFun')

    @allure.severity('normal')
    @allure.title('功能寻址-扩展会话-NRC12测试')
    @allure.description('功能寻址扩展会话下NRC12')
    @pytest.mark.parametrize('req,resp', ControlDTCSetting_NRC12,
                           ids=[f"Req:{req}" for req, _ in ControlDTCSetting_NRC12])
    def test_ControlDTCSetting_NRC12_Extended_Func(self, action, Driver, req, resp):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, req, '', 3, iStep, False, 'UDSFun')

    @allure.severity('critical')
    @allure.title('功能寻址-扩展会话-NRC12/NRC13优先级验证')
    @allure.description('验证功能寻址扩展会话下NRC响应顺序：12 > 13')
    def test_ControlDTCSetting_NRC12_NRC13_Priority_Extended_Func(self, action, Driver):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '85 05 01', '', 3, iStep, False, 'UDSFun')

    @allure.severity('critical')
    @allure.title('功能寻址-默认会话-NRC7F/NRC22优先级验证')
    @allure.description('验证功能寻址默认会话下NRC响应顺序：7F > 22')
    def test_ControlDTCSetting_NRC7F_NRC22_Priority_Default_Func(self, action, Driver):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '10 01', '50 01', 0, iStep, False)
        iStep = Driver['CAN'].SetVehicleSpeed(Driver, iStep, 5)
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '85 01', '', 0, iStep, False, 'UDSFun')
        iStep = Driver['CAN'].SetVehicleSpeed(Driver, iStep, 0)
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '85 01', '', 0, iStep, False, 'UDSFun')

    @allure.severity('critical')
    @allure.title('功能寻址-扩展会话-关闭DTC控制功能验证')
    @allure.description('验证功能寻址扩展会话下关闭DTC控制功能验证')
    def test_ControlDTCSetting_OFF_Extended_Func(self, action, Driver):
        iStep = 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '10 03', '50 03', 0, iStep, False)
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '85 02', 'C5 02', 0, iStep, False, 'UDSFun')
        # 设置电源电压为8v并等待3.5s,生成低压故障
        iStep = Driver['CAN'].SetVolt(Driver, 8.3, 2, iStep)
        for i in range(2): # 重复3次
            with allure.step(f'Step{iStep}:等待3s'): # type: ignore
                iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
                time.sleep(2)
                iStep += 1
        with allure.step(f'Step{iStep}:关闭DTC检测,应无法生成低压故障'): # type: ignore
            a,b,c=Driver['UDS'].search_DTC([0x19, 0x02, 0x09], [0x91, 0x17, 0x16, 0x09], 1)
            with assume: assert a == False, logging.error('检测到低压故障,未关闭DTC控制功能')
            iStep += 1
        iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '85 01', 'C5 01', 0, iStep, False, 'UDSFun')
        for i in range(2): # 重复3次
            with allure.step(f'Step{iStep}:等待3s'): # type: ignore
                iStep, _, _ = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
                time.sleep(2)
                iStep += 1
        with allure.step(f'Step{iStep}:打开DTC检测,应生成低压故障'): # type: ignore
            a,b,c=Driver['UDS'].search_DTC([0x19, 0x02, 0x09], [0x91, 0x17, 0x16, 0x09], 1)
            with assume: assert a == True, logging.error('未检测到低压故障,未打开DTC控制功能')
            iStep += 1
        iStep = Driver['CAN'].SetVolt(Driver, 12, 1, iStep)
# endregion